package com.jieao.common.utils.date;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
  *  时间工具类
  * @Author weifanl
  * @Date 11:31 2020/5/13
  **/
public class DateUtil {
    public final static String DATE_FORMAT_YMD_1 = "yyyyMMdd";
    public final static String DATE_FORMAT_YMD_2 = "yyyy-MM-dd";
    public final static String DATE_FORMAT_YMD_3 = "yyyy/MM/dd";
    public final static String DATE_FORMAT_YMD_4 = "yyyy年MM月dd日";

    public final static String DATE_FORMAT_HMS_1 = "HHmmss";
    public final static String DATE_FORMAT_HMS_2 = "HH:mm:ss";
    public final static String DATE_FORMAT_HMS_3 = "HH时mm分ss秒";

    public final static String DATE_FORMAT_YMDHMS_1 = "yyyyMMddHHmmss";
    public final static String DATE_FORMAT_YMDHMS_2 = "yyyy-MM-dd HH:mm:ss";
    public final static String DATE_FORMAT_YMDHMS_3 = "yyyy/MM/dd HH:mm:ss";
    public final static String DATE_FORMAT_YMDHMS_4 = "yyyy年MM月dd日 HH时mm分ss秒";

    public final static String DATE_FORMAT_YMDHM_1 = "yyyyMMddHHmm";
    public final static String DATE_FORMAT_YMDHM_2 = "yyyy-MM-dd HH:mm";
    public final static String DATE_FORMAT_YMDHM_3 = "yyyy/MM/dd HH:mm";
    public final static String DATE_FORMAT_YMDHM_4 = "yyyy年MM月dd日 HH时mm分";

    private static String[] parsePatterns = {
            DATE_FORMAT_YMD_1, DATE_FORMAT_YMD_2,DATE_FORMAT_YMD_3,DATE_FORMAT_YMD_4,
            DATE_FORMAT_YMDHMS_1,DATE_FORMAT_YMDHMS_2,DATE_FORMAT_YMDHMS_3,DATE_FORMAT_YMDHMS_4,
            DATE_FORMAT_YMDHM_1,DATE_FORMAT_YMDHM_2,DATE_FORMAT_YMDHM_3,DATE_FORMAT_YMDHM_4};

    /**
     * 每天的毫秒数 8640000.
     */
    public static final long MILLISECONDS_PER_DAY = 86400000L;

    /**
     * 每周的天数.
     */
    public static final long DAYS_PER_WEEK = 7L;

    /**
     * 每小时毫秒数.
     */
    public static final long MILLISECONDS_PER_HOUR = 3600000L;

    /**
     * 每分钟秒数.
     */
    public static final long SECONDS_PER_MINUTE = 60L;

    /**
     * 每小时秒数.
     */
    public static final long SECONDS_PER_HOUR = 3600L;

    /**
     * 每天秒数.
     */
    public static final long SECONDS_PER_DAY = 86400L;

    /**
     * 每个月秒数，默认每月30天.
     */
    public static final long SECONDS_PER_MONTH = 2592000L;

    /**
     * 每年秒数，默认每年365天.
     */
    public static final long SECONDS_PER_YEAR = 31536000L;

    /**
     * 获取当前时间指定格式下的字符串.
     * @param pattern
     *            转化后时间展示的格式，例如"yyyy-MM-dd"，"yyyy-MM-dd HH:mm:ss"等
     * @return String 格式转换之后的时间字符串.
     * @since 1.0
     */
    public static String getDate(String pattern) {
        return DateFormatUtils.format(new Date(), pattern);
    }

    /**
     * 获取指定日期的字符串格式.
     * @param date  需要格式化的时间，不能为空
     * @param pattern 时间格式，例如"yyyy-MM-dd"，"yyyy-MM-dd HH:mm:ss"等
     * @return String 格式转换之后的时间字符串.
     * @since 1.0
     */
    public static String getDate(Date date, String pattern) {
        return DateFormatUtils.format(date, pattern);
    }

    /**
     * 获取日期时间字符串，默认格式为（yyyy-MM-dd HH:mm:ss）.
     * @param date 需要转化的日期时间
     * @param pattern 时间格式，例如"yyyy-MM-dd" "HH:mm:ss" "E"等
     * @return String 格式转换后的时间字符串
     * @since 1.0
     */
    public static String formatDate(Date date, Object... pattern) {
        String formatDate = null;
        if (pattern != null && pattern.length > 0) {
            formatDate = DateFormatUtils.format(date, pattern[0].toString());
        } else {
            formatDate = DateFormatUtils.format(date, DateUtil.DATE_FORMAT_YMDHMS_2);
        }
        return formatDate;
    }

    /**
     * 根据Date获取格式化数据
     * @param date date对象
     * @param format 格式
     * @return 格式化后的数据
     */
    public static String date2Str(Date date, String format ){
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(date);
    }

    /**
     * 根据毫秒数获取格式化数据
     * @param millis 毫秒数
     * @param format 格式
     * @return 格式化后的数据
     */
    public static String millis2Str(String millis, String format){
        return date2Str(new Date(Long.valueOf(millis)), format);
    }

    /**
     * 根据Calendar获取格式化数据
     * @param calendar Calendar对象
     * @param format 格式
     * @return 格式化后的数据
     */
    public static String calendar2Str(Calendar calendar, String format){
        return date2Str(new Date(calendar.getTimeInMillis()), format);
    }

    /**
     * 根据格式化数据获取Date对象
     * @param str 格式化数据
     * @param format 格式
     * @param defaultValue 在转换Date对象失败时返回默认Date对象
     * @return 在转换Date对象失败时返回默认Date对象
     */
    public static Date str2Date(String str, String format, Date defaultValue){
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        try {
            return sdf.parse(str);
        } catch (ParseException e) {
            return defaultValue;
        }
    }
    public static Date str2Date(String str, String format){
        return str2Date(str,format,null);
    }
    public static Date str2Date(String str){
        if (str == null) {
            return null;
        }
        try {
            return org.apache.commons.lang3.time.DateUtils.parseDate(str.toString(), parsePatterns);
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 获取当前年份字符串.
     * @return String 当前年份字符串，例如 2015
     * @since 1.0
     */
    public static String getYear() {
        return formatDate(new Date(), "yyyy");
    }

    /**
     * 获取当前月份字符串.
     * @return String 当前月份字符串，例如 08
     * @since 1.0
     */
    public static String getMonth() {
        return formatDate(new Date(), "MM");
    }

    /**
     * 获取当前天数字符串.
     * @return String 当前天数字符串，例如 11
     * @since 1.0
     */
    public static String getDay() {
        return formatDate(new Date(), "dd");
    }

    /**
     * 获取当前星期字符串.
     * @return String 当前星期字符串，例如星期二
     * @since 1.0
     */
    public static String getWeek() {
        return formatDate(new Date(), "E");
    }

    /**
     * 将 Date 日期转化为 Calendar 类型日期.
     * @param date   给定的时间，若为null，则默认为当前时间
     * @return Calendar Calendar对象
     * @since 1.0
     */
    public static Calendar getCalendar(Date date) {
        Calendar calendar = Calendar.getInstance();
        if (date != null) {
            calendar.setTime(date);
        }
        return calendar;
    }

    /**
     * 格式化Date时间
     * @param time       Date类型时间
     * @param timeFromat String类型格式
     * @return 格式化后的字符串
     */
    public static String parseDateToStr(String timeFromat, Date time) {
        DateFormat dateFormat = new SimpleDateFormat(timeFromat);
        return dateFormat.format(time);
    }
    /**
     * 通过年月获取月的最后一天
     * @Author weifanl
     * @Date 17:50 2020/6/28
     * @Param [year, month]
     * @return java.lang.String "2019-01-31"
     **/
    public static String getLastDayOfMonth(Integer year,Integer month) {
        Calendar cal = Calendar.getInstance();
        // 设置年份
        cal.set(Calendar.YEAR, year);
        // 设置月份
        //设置当前月的上一个月
        cal.set(Calendar.MONTH, month);
        // 获取某月最大天数
        //获取月份中的最小值，即第一天
        int lastDay = cal.getMinimum(Calendar.DATE);
        // 设置日历中月份的最大天数
        //上月的第一天减去1就是当月的最后一天
        cal.set(Calendar.DAY_OF_MONTH, lastDay - 1);
        // 格式化日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        return sdf.format(cal.getTime());
    }

    /**
     * 根据年月获取当月最后一天
     * @param dateStr  2020-06
     * @return  2020-06-30 23：59：59
     */
    public static String getMonthLastDay(String dateStr){
        if(StringUtils.isBlank(dateStr)){
            return null;
        }
        String[] arr = dateStr.split("-");
        int year = Integer.parseInt(arr[0]);
        int month = Integer.parseInt(arr[1]);
        Calendar cal = Calendar.getInstance();
        // 设置年份
        cal.set(Calendar.YEAR, year);
        // 设置月份
        cal.set(Calendar.MONTH, month - 1);
        // 获取某月最大天数
        int lastDay=0;
        //2月的平年瑞年天数
        if(month == 2) {
            lastDay = cal.getLeastMaximum(Calendar.DAY_OF_MONTH);
        }else {
            lastDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
        }
        // 设置日历中月份的最大天数
        cal.set(Calendar.DAY_OF_MONTH, lastDay);
        // 格式化日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String lastDayOfMonth = sdf.format(cal.getTime())+" 23:59:59";
        return lastDayOfMonth;
    }
}
